﻿using System;
using Windows.ApplicationModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using RockHopper.TrainingCalculator.WinRT.Common;
using RockHopper.Common.Commanding;
using Windows.UI.Xaml.Media.Animation;

namespace RockHopper.TrainingCalculator.WinRT.Controls
{
    public class TileControl : Control
    {
        private Canvas canvas;
        private Image image;
        private Storyboard currentStoryboard;
        private static readonly Random randomBeginTime = new Random();

        public TileControl()
        {
            DefaultStyleKey = typeof(TileControl);
        }

        public static readonly DependencyProperty LabelProperty =
            DependencyPropertyDescriptor.CreateProperty<TileControl, string>("Label");

        public string Label
        {
            get { return (string)GetValue(LabelProperty); }
            set { SetValue(LabelProperty, value); }
        }
       
        public static readonly DependencyProperty LiveTileInfoProperty =
            DependencyPropertyDescriptor.CreateProperty<TileControl, string>("LiveTileInfo");

        public string LiveTileInfo
        {
            get { return (string)GetValue(LiveTileInfoProperty); }
            set { SetValue(LiveTileInfoProperty, value); }
        }
        
        public static readonly DependencyProperty TileCommandProperty =
            DependencyPropertyDescriptor.CreateProperty<TileControl, DelegateCommand>("TileCommand");

        public DelegateCommand TileCommand
        {
            get { return (DelegateCommand)GetValue(TileCommandProperty); }
            set { SetValue(TileCommandProperty, value); }
        }

        public string LogoImageKey { get; set; }

        public int LiveTileInfoFontSize { get; set; }

        public bool EnableLiveTile { get; set; }

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            InitImage();
            InitCanvas();
        }

        protected override void OnPointerPressed(PointerRoutedEventArgs e)
        {
            CapturePointer(e.Pointer);
            VisualStateManager.GoToState(this, "PointerDown", true);
        }

        protected override void OnPointerReleased(PointerRoutedEventArgs e)
        {
            VisualStateManager.GoToState(this, "PointerUp", true);
            ReleasePointerCapture(e.Pointer);

            if (TileCommand != null && TileCommand.CanExecute(this))
                TileCommand.Execute(this);
        }

        private Storyboard CreateStoryboard(UIElement[] elements)
        {
            var beginTime = TimeSpan.FromSeconds(randomBeginTime.Next(3, 7));
            var storyboard = new Storyboard {BeginTime = beginTime};
            AddAnimation(storyboard, 0, -Height, elements[0]);
            AddAnimation(storyboard, Height, 0, elements[1]);
            storyboard.Completed += OnStoryboardCompleted;
            return storyboard;
        }

        private void InitImage()
        {
            image = (Image)GetTemplateChild("ImagePart");

            if (image != null && LogoImageKey != null)
            {
                image.Width = 0.9*Width;
                image.Height = 0.9*Height;
                image.Source = Common.Resources.TrainingStyles.Get<ImageSource>(LogoImageKey);
            }
        }

        private void InitCanvas()
        {
            if (!EnableLiveTile) return;

            canvas = (Canvas)GetTemplateChild("CanvasPart");

            if (canvas != null && canvas.Children.Count == 2)
            {
                if (!DesignMode.DesignModeEnabled)
                {
                    currentStoryboard = CreateStoryboard(GetChildOrder());
                    currentStoryboard.Begin();
                }
            }

            if (LiveTileInfoFontSize == 0) return;

            var liveInfoTextBlock = (TextBlock) GetTemplateChild("LiveTileInfoTextBlock");
            liveInfoTextBlock.FontSize = LiveTileInfoFontSize;
        }

        private static void AddAnimation(Storyboard storyboard, double from, double to, UIElement element)
        {
            var duration = new Duration(TimeSpan.FromMilliseconds(500));
            var animation = new DoubleAnimation
                {
                    From = from,
                    To = to,
                    Duration = duration,
                    EasingFunction = new PowerEase {EasingMode = EasingMode.EaseOut}
                };
            Storyboard.SetTarget(animation, element);
            Storyboard.SetTargetProperty(animation, "(Canvas.Top)");
            storyboard.Children.Add(animation);
        }

        private UIElement[] GetChildOrder()
        {
            var top = Canvas.GetTop(canvas.Children[0]);
            return top >= Height 
                ? new[] {canvas.Children[1], canvas.Children[0]} 
                : new[] {canvas.Children[0], canvas.Children[1]};
        }

        private void OnStoryboardCompleted(object sender, object e)
        {
            var top = Canvas.GetTop(canvas.Children[0]);
            Canvas.SetTop(top < 0 ? canvas.Children[0] : canvas.Children[1], Height);
            currentStoryboard = CreateStoryboard(GetChildOrder());
            currentStoryboard.Begin();
        }
    }
}
